package com.siyoumi.app.test.sys;

import com.siyoumi.app.sys.entity.AesKi;
import com.siyoumi.component.http.InputData;
import com.siyoumi.component.http.XHttpContext;
import com.siyoumi.entity.SysAccsuperConfig;
import com.siyoumi.service.SysAccsuperConfigService;
import com.siyoumi.test.TestController;
import com.siyoumi.test.annotation.TestClass;
import com.siyoumi.util.*;
import com.siyoumi.validator.XValidator;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;

//接口
@TestClass(
        runMethods = "login_test"
)
@Slf4j
@RestController
@RequestMapping("/test/test_aes")
public class testAes
        extends TestController {
    //http://dev.x.siyoumi.com/test/test_aes/gan_key
    @SneakyThrows
    @GetMapping("gan_key")
    public XReturn ganKey() {
        XReturn r = XReturn.getR(0);

        r.setData("key,iv", XAes.genKeyAndIv());
        r.setData("uuid", XApp.getUUID());

        return r;
    }

    //http://dev.x.siyoumi.com/test/test_aes/config_enc
    @SneakyThrows
    @GetMapping("config_enc")
    public XReturn configEnc() {
        String text = input("text");
        if (XStr.isNullOrEmpty(text)) {
            text = "123绕伟平";
        }
        String token = input("token");
        if (XStr.isNullOrEmpty(token)) {
            SysAccsuperConfig config = XHttpContext.getXConfig();
            token = config.getAconfig_token();
        }

        XReturn r = XReturn.getR(0);

        AesKi aesKi = AesKi.of(token);
        String textEnc = aesKi.encTxt(text);
        String textDec = aesKi.decTxt(textEnc);

        r.setData("aes_key", aesKi.getKey());
        r.setData("aes_iv", aesKi.getIv());
        r.setData("txt_enc", textEnc);
        r.setData("txt_dec", textDec);

        return r;
    }

    //http://dev.x.siyoumi.com/test/test_aes/config_dec
    @SneakyThrows
    @GetMapping("config_dec")
    public XReturn configDec() {
        String text = input("text");
        XValidator.isNullOrEmpty(text, "miss text");
        String token = input("token");
        if (XStr.isNullOrEmpty(token)) {
            SysAccsuperConfig config = XHttpContext.getXConfig();
            token = config.getAconfig_token();
        }

        XReturn r = XReturn.getR(0);

        AesKi aesKi = AesKi.of(token);
        String textDec = aesKi.decTxt(text);

        r.setData("aes_key", aesKi.getKey());
        r.setData("aes_iv", aesKi.getIv());
        r.setData("txt_dec", textDec);

        return r;
    }

    @SneakyThrows
    @GetMapping("text")
    public XReturn textTo() {
        XReturn r = XReturn.getR(0);

        String key = "o55g0zQ6mDP+5t82itc6ZA==";
        String ivStr = "abcdefghijklmnop";
        IvParameterSpec iv = new IvParameterSpec(ivStr.getBytes(StandardCharsets.UTF_8));

        SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");

        String text = "张先生abc";

        r.setData("text", text);
        String textEnc = encrypt(text, secretKeySpec, iv);
        r.setData("text_enc", textEnc);
        String textDec = decrypt(textEnc, secretKeySpec, iv);
        r.setData("text_dec", textDec);

        return r;
    }


    /**
     * 加密数据
     *
     * @param data      待加密的数据
     * @param secretKey AES 密钥
     * @return Base64 编码的加密数据
     */
    public static String encrypt(String data, SecretKey secretKey, IvParameterSpec iv) throws Exception {
        // 初始化加密器，指定 AES/ECB/PKCS5Padding
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);

        // 加密
        byte[] decryptedBytes = cipher.doFinal(data.getBytes());

        // 返回解密后的字符串
        return Base64.getEncoder().encodeToString(decryptedBytes);
    }


    /**
     * 解密数据
     *
     * @param encryptedData Base64 编码的加密数据
     * @param key           AES 密钥
     * @return 解密后的原始数据
     */
    public static String decrypt(String encryptedData, SecretKey key, IvParameterSpec iv) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");

        cipher.init(Cipher.DECRYPT_MODE, key, iv);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }
}
